package ling.common;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;

public class ObjectConverter {

    /**
     * 将Map转换为对象，忽略键的大小写和特殊字符（如下划线）
     * @param map 源数据Map
     * @param targetClass 目标对象的Class
     * @return 转换后的对象
     */
    public static <T> T convert(Map<?, ?> map, Class<T> targetClass) {
        try {
            T instance = targetClass.getDeclaredConstructor().newInstance();
            // 获取目标类及其所有父类的字段（包括私有字段）
            List<Field> fields = getAllFields(targetClass);

            for (Field field : fields) {
                // 跳过静态和final字段
                if (Modifier.isStatic(field.getModifiers()) || Modifier.isFinal(field.getModifiers())) {
                    continue;
                }

                String fieldName = field.getName();
                // 规范化字段名：小写 + 移除分隔符（如下划线）
                String normalizedFieldName = normalizeName(fieldName);

                // 在Map中查找匹配的键（忽略大小写和字符）
                Optional<?> mapKey = map.keySet().stream()
                        .filter(key -> normalizeName(key.toString()).equals(normalizedFieldName))
                        .findFirst();

                if (mapKey.isPresent()) {
                    Object value = map.get(mapKey.get());
                    setFieldValue(instance, field, value);
                }
            }
            return instance;
        } catch (Exception e) {
            throw new RuntimeException("Map转对象失败", e);
        }
    }

    // 获取类及其父类的所有字段
    private static List<Field> getAllFields(Class<?> clazz) {
        List<Field> fields = new ArrayList<>();
        while (clazz != null) {
            Collections.addAll(fields, clazz.getDeclaredFields());
            clazz = clazz.getSuperclass();
        }
        return fields;
    }

    // 规范化名称：转为小写并移除分隔符
    private static String normalizeName(String name) {
        return name.replaceAll("_", "").toLowerCase();
    }

    // 设置字段值（支持类型转换）
    private static void setFieldValue(Object obj, Field field, Object value) throws IllegalAccessException {
        if (value == null) return;

        field.setAccessible(true);
        Class<?> fieldType = field.getType();

        try {
            // 基础类型转换
            if (fieldType == int.class || fieldType == Integer.class) {
                field.set(obj, Integer.parseInt(value.toString()));
            } else if (fieldType == long.class || fieldType == Long.class) {
                field.set(obj, Long.parseLong(value.toString()));
            } else if (fieldType == double.class || fieldType == Double.class) {
                field.set(obj, Double.parseDouble(value.toString()));
            } else if (fieldType == boolean.class || fieldType == Boolean.class) {
                field.set(obj, Boolean.parseBoolean(value.toString()));
            } else if (fieldType == BigDecimal.class) {
                field.set(obj, new BigDecimal(value.toString()));
            } else if (fieldType == Date.class) {
                // 支持多种日期格式（按需扩展）
                field.set(obj, parseDate(value.toString()));
            } else {
                // 其他类型直接赋值
                field.set(obj, value);
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("字段类型转换失败: " + field.getName(), e);
        }
    }

    // 简易日期解析
    private static Date parseDate(String dateStr)  {
        SimpleDateFormat[] formats = {
                new SimpleDateFormat("yyyy-MM-dd"),
                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        };
        for (SimpleDateFormat format : formats) {
            try {
                return format.parse(dateStr);
            } catch (ParseException ignored) {}
        }
        return  null;
        //throw new ParseException("不支持的日期格式: " + dateStr, 0);
    }
}
